package tp.badugi.bot;

import static org.junit.Assert.*;

import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

public class CardExchangeWithDoublesTest {
	
	private BotPrudentCardExchangeStrategy botCardExchanger;
	
	@Before
	public void before() throws Exception {
		this.botCardExchanger = new BotPrudentCardExchangeStrategy();
	}
	
	@After
	public void after() throws Exception {
	}
	
	
	// ----------------------------- Duplicate Exchange ------------------------------
	// Duplicate Color
	
	//2
	@Test
	public void Duplicate_Exchange_Given_AS_KS_3C_6S_Exchange_KS(){
		String givenCards[] = new String[]{"AS","KS","3C","6D"};
		String expectedResult[] = new String[]{"KS"};
		
		String botResult[] = this.botCardExchanger.exchangeCards(givenCards);
		
		Assert.assertArrayEquals(expectedResult, botResult);
	}
	
	@Test
	public void Duplicate_Exchange_Given_4D_8H_9S_6S_Exchange_9S(){
		String givenCards[] = new String[]{"4D","8H","9S","6S"};
		String expectedResult[] = new String[]{"9S"};
		
		String botResult[] = this.botCardExchanger.exchangeCards(givenCards);
		
		Assert.assertArrayEquals(expectedResult, botResult);
	}
	
	@Test
	public void Duplicate_Exchange_Given_5D_QH_AS_6D_Exchange_6D(){
		String givenCards[] = new String[]{"5D","QH","AS","6D"};
		String expectedResult[] = new String[]{"6D"};
		
		String botResult[] = this.botCardExchanger.exchangeCards(givenCards);
		
		Assert.assertArrayEquals(expectedResult, botResult);
	}
	//2
	
	//3
	@Test
	public void Duplicate_Exchange_Given_6D_7H_TH_9H_Exchange_9H_TH(){
		String givenCards[] = new String[]{"6D","7H","TH","9H"};
		String expectedResult[] = new String[]{"TH","9H"};
		
		String botResult[] = this.botCardExchanger.exchangeCards(givenCards);
		
		List<String> botResultList = Arrays.asList(botResult);
		
		List<String> expectedResultList = Arrays.asList(expectedResult);
		
		assertTrue((expectedResultList.containsAll(botResultList) && botResultList.containsAll(expectedResultList)) );
	}
	//3
	
	//2+2
	@Test
	public void Duplicate_Exchange_Given_7S_2C_8S_6C_Exchange_8S_6C(){
		String givenCards[] = new String[]{"7S","2C","8S","6C"};
		String expectedResult[] = new String[]{"8S","6C"};
		
		String botResult[] = this.botCardExchanger.exchangeCards(givenCards);
		
		List<String> botResultList = Arrays.asList(botResult);
		
		List<String> expectedResultList = Arrays.asList(expectedResult);
		
		assertTrue((expectedResultList.containsAll(botResultList) && botResultList.containsAll(expectedResultList)) );
	}
	
	@Test
	public void Duplicate_Exchange_Given_2H_8C_5H_4C_Exchange_8C_5H(){
		String givenCards[] = new String[]{"2H","8C","5H","4C"};
		String expectedResult[] = new String[]{"8C","5H"};
		
		String botResult[] = this.botCardExchanger.exchangeCards(givenCards);
		
		List<String> botResultList = Arrays.asList(botResult);
		
		List<String> expectedResultList = Arrays.asList(expectedResult);
		
		assertTrue((expectedResultList.containsAll(botResultList) && botResultList.containsAll(expectedResultList)) );
	}
	//2+2
	
	//4
	@Test
	public void Duplicate_Exchange_Given_2D_QD_3D_AD_Exchange_2D_QD_3D(){
		String givenCards[] = new String[]{"2D","QD","3D","AD"};
		String expectedResult[] = new String[]{"2D","QD","3D"};
		
		String botResult[] = this.botCardExchanger.exchangeCards(givenCards);
		
		List<String> botResultList = Arrays.asList(botResult);
		
		List<String> expectedResultList = Arrays.asList(expectedResult);
		
		assertTrue((expectedResultList.containsAll(botResultList) && botResultList.containsAll(expectedResultList)) );
	}
	//4
	// Duplicate Color
	
	// Duplicate Values Different Color
	@Test
	//2
	public void Duplicate_Exchange_Given_5H_QD_QC_4S_Exchange_Q(){
		String givenCards[] = new String[]{"5H","QD","QC","4S"};
		String expectedResult1[] = new String[]{"QD"};
		String expectedResult2[] = new String[]{"QC"};
		
		String botResult[] = this.botCardExchanger.exchangeCards(givenCards);
		
		
		assertTrue(Arrays.equals(botResult, expectedResult1) || Arrays.equals(botResult, expectedResult2));
	}
	//2
	
	//2+2
	@Test
	public void Duplicate_Exchange_Given_2H_2D_5S_5C_Exchange_2_5(){
		String givenCards[] = new String[]{"2H","2D","5S","5C"};
		String expectedResult1[] = new String[]{"2H","5S"};
		String expectedResult2[] = new String[]{"2H","5C"};
		String expectedResult3[] = new String[]{"2D","5S"};
		String expectedResult4[] = new String[]{"2D","5C"};
		
		String botResult[] = this.botCardExchanger.exchangeCards(givenCards);
		
		List<String> botResultList = Arrays.asList(botResult);
		
		List<String> expectedResult1List = Arrays.asList(expectedResult1);
		List<String> expectedResult2List = Arrays.asList(expectedResult2);
		List<String> expectedResult3List = Arrays.asList(expectedResult3);
		List<String> expectedResult4List = Arrays.asList(expectedResult4);
		
		assertTrue((expectedResult1List.containsAll(botResultList) && botResultList.containsAll(expectedResult1List)) ||
					(expectedResult2List.containsAll(botResultList) && botResultList.containsAll(expectedResult2List)) ||
					(expectedResult3List.containsAll(botResultList) && botResultList.containsAll(expectedResult3List)) ||
					(expectedResult4List.containsAll(botResultList) && botResultList.containsAll(expectedResult4List)));
	}
	//2+2
	
	//3
	@Test
	public void Duplicate_Exchange_Given_AD_AH_AS_QC_Exchange_Two_A(){
		String givenCards[] = new String[]{"AD","AH","AS","QC"};
		String expectedResult1[] = new String[]{"AD","AH"};
		String expectedResult2[] = new String[]{"AH","AS"};
		String expectedResult3[] = new String[]{"AD","AS"};
		
		String botResult[] = this.botCardExchanger.exchangeCards(givenCards);
		
		List<String> botResultList = Arrays.asList(botResult);
		
		List<String> expectedResult1List = Arrays.asList(expectedResult1);
		List<String> expectedResult2List = Arrays.asList(expectedResult2);
		List<String> expectedResult3List = Arrays.asList(expectedResult3);
		
		assertTrue((expectedResult1List.containsAll(botResultList) && botResultList.containsAll(expectedResult1List)) ||
					(expectedResult2List.containsAll(botResultList) && botResultList.containsAll(expectedResult2List)) ||
					(expectedResult3List.containsAll(botResultList) && botResultList.containsAll(expectedResult3List)) );
	}
	//3
	
	//4
	@Test
	public void Duplicate_Exchange_Given_2S_2C_2D_2H_Exchange_Three(){
		String givenCards[] = new String[]{"2S","2C","2D","2H"};
		int expectedResult = 3;
		
		String botResult[] = this.botCardExchanger.exchangeCards(givenCards);
		
		assertTrue(botResult.length == expectedResult);
	}
	//4
	// Duplicate Values Different Color
	
	// Two Duplicated Values And Duplicate Colors
	// Inner Color Exchange One
	@Test
	public void Duplicate_Exchange_Given_4S_4D_3H_5S_Exchange_4S(){
		String givenCards[] = new String[]{"4S","4D","3H","5S"};
		String expectedResult[] = new String[]{"4S"};
		
		String botResult[] = this.botCardExchanger.exchangeCards(givenCards);
		
		Assert.assertArrayEquals(expectedResult, botResult);
	}
	
	// Inner Color Exchange Two
	@Test
	public void Duplicate_Exchange_Given_3D_9H_KH_9C_Exchange_KH_9C(){
		String givenCards[] = new String[]{"3D","9H","KH","9C"};
		String expectedResult[] = new String[]{"KH","9C"};
		
		String botResult[] = this.botCardExchanger.exchangeCards(givenCards);
		
		List<String> botResultList = Arrays.asList(botResult);
		
		List<String> expectedResultList = Arrays.asList(expectedResult);
		
		assertTrue((expectedResultList.containsAll(botResultList) && botResultList.containsAll(expectedResultList)) );
	}
	
	@Test
	public void Duplicate_Exchange_Given_9S_9D_3H_5S_Exchange_9S_9D(){
		String givenCards[] = new String[]{"9S","9D","3H","5S"};
		String expectedResult[] = new String[]{"5S","9D"};
		
		String botResult[] = this.botCardExchanger.exchangeCards(givenCards);
		
		List<String> botResultList = Arrays.asList(botResult);
		
		List<String> expectedResultList = Arrays.asList(expectedResult);
		
		assertTrue((expectedResultList.containsAll(botResultList) && botResultList.containsAll(expectedResultList)) );
	}
	
	// Double Inner Color
	@Test
	public void Duplicate_Exchange_Given_3C_3H_8C_2H_Exchange_3H_8C(){
		String givenCards[] = new String[]{"3C","3H","8C","2H"};
		String expectedResult[] = new String[]{"3H","8C"};
		
		String botResult[] = this.botCardExchanger.exchangeCards(givenCards);
		
		List<String> botResultList = Arrays.asList(botResult);
		
		List<String> expectedResultList = Arrays.asList(expectedResult);
		
		assertTrue((expectedResultList.containsAll(botResultList) && botResultList.containsAll(expectedResultList)) );
	}
	
	// Outer Color
	@Test
	public void Duplicate_Exchange_Given_3S_3D_4C_6C_Exchange_3_6C(){
		String givenCards[] = new String[]{"3S","3D","4C","6C"};
		String expectedResult1[] = new String[]{"3S","6C"};
		String expectedResult2[] = new String[]{"3D","6C"};
		
		String botResult[] = this.botCardExchanger.exchangeCards(givenCards);
		
		List<String> botResultList = Arrays.asList(botResult);
		
		List<String> expectedResult1List = Arrays.asList(expectedResult1);
		List<String> expectedResult2List = Arrays.asList(expectedResult2);
		
		assertTrue((expectedResult1List.containsAll(botResultList) && botResultList.containsAll(expectedResult1List)) ||
					(expectedResult2List.containsAll(botResultList) && botResultList.containsAll(expectedResult2List)) );
	}
	// Two Duplicated Values And Duplicate Colors
	
	// Three Duplicated Values And Duplicate Colors
	@Test
	public void Duplicate_Exchange_Given_AD_AH_AS_QS_Exchange_AD_AH_QS(){
		String givenCards[] = new String[]{"AD","AH","AS","QS"};
		String expectedResult[] = new String[]{"AD","AH","QS"};
		
		String botResult[] = this.botCardExchanger.exchangeCards(givenCards);
		
		List<String> botResultList = Arrays.asList(botResult);
		
		List<String> expectedResultList = Arrays.asList(expectedResult);
		
		assertTrue((expectedResultList.containsAll(botResultList) && botResultList.containsAll(expectedResultList)) );
	}
	// Three Duplicated Values And Duplicate Colors
	// ----------------------------- Duplicate Exchange ------------------------------
}
